#include <iostream>
#include <stdlib.h>
using namespace std;

typedef struct Nodo{
    int dato;
    struct Nodo *siguiente;
    struct Nodo *anterior;
}Nodo;

typedef struct
{
    Nodo *inicio;
}lista;

void inicializacion (lista * tas){
    tas->inicio = NULL;
}

int agregaralfinal (lista * tas, int dato)
{
    Nodo *nuevo_elemento;
    Nodo *actual;
    if ((nuevo_elemento = (Nodo *) malloc (sizeof (Nodo))) == NULL)
        return -1;

    nuevo_elemento->dato=dato;
    nuevo_elemento->siguiente = NULL;

    if(tas->inicio==NULL)
    {
        tas->inicio=nuevo_elemento;
    }else
    {
        actual=tas->inicio;
        while(1)
        {
            if (actual->siguiente==NULL)
                break;

            actual=actual->siguiente;
        }
        actual->siguiente=nuevo_elemento;
        nuevo_elemento->anterior=actual;
    }


}
int agregaralprincipio(lista*tas,int dato)
{
    Nodo *nuevo_elemento;
    if ((nuevo_elemento = (Nodo *) malloc (sizeof (Nodo))) == NULL)
        return -1;

    nuevo_elemento->dato= dato;
    nuevo_elemento->siguiente = tas->inicio;
    tas->inicio=nuevo_elemento;
    nuevo_elemento->anterior=NULL
    nuevo_elemento->siguiente->anterior=nuevo_elemento;
}
int eliminarprimero()(lista * tas)
{
    Nodo *sup_elemento;
    if (tas->inicio==NULL)
        return -1;
    sup_elemento = tas->inicio;
    tas->inicio = tas->inicio->siguiente;
    if(tas->inicio!=NULL)
    {
        tas->inicio->anterior=NULL;
    }
    free (sup_elemento);
    return 0;
}
int eliminarultimo(lista * tas){

    Nodo *sup_elemento;
    if (tas->inicio==NULL)
        return -1;
    sup_elemento=tas->inicio;

    while(1)
    {

        if(sup_elemento->siguiente==NULL)
        {
           if(sup_elemento->anterior!=NULL)
           {
                sup_elemento->anterior->siguiente=NULL;
                break;
           }else
           {
               tas->inicio=NULL;
               break;
           }


        }

        sup_elemento=sup_elemento->siguiente;

    }
    free(sup_elemento);

}
void muestra (lista * tas){
    Nodo *actual;

    actual = tas->inicio;
    if (actual==NULL) return;
    while(1)
    {
        cout<< actual->dato <<endl;
        if (!actual->siguiente) break;
        actual = actual->siguiente;
    }


}

void buscarnodo(lista*tas,int opnodo)
{
    nodo *actual;
    actual=tas->inicio;
    if (actual==NULL) return;
    while (1)
    {
        if(actual->dato==opnodo)
        {
            cout<<"Esite";
        }else
        if(actual->siguiente==NULL)
        break;
        actual=actual->siguiente;

    }
}

void agregarordenado(lista *tas,int dato1 )
{
    Nodo *nuevo_elemento;
    Nodo *actual;
    if ((nuevo_elemento = (Nodo *) malloc (sizeof (Nodo))) == NULL)
        return -1;


    nuevo_elemento->dato=dato1;
    actual=tas->inicio;

    if(tas->inicio==NULL)
    {
        tas->inicio=nuevo_elemento;
          nuevo_elemento->siguiente=NULL;
        nuevo_elemente->anterior=NULL;

    }else
    {
        while(1)
        {

            if (nuevo_elemento->dato < actual->dato)
            {
                if(actual->anterior==NULL)
                {
                    nuevo_elemento->anterior = NULL ;
                    nuevo_elemento->siguiente=tas->inicio;
                    tas->inicio=nuevo_elemento;
                    actual->anterior=nuevo_elemento;

                }
                else
                {
                    nuevo_elemento->siguiente=actual;
                    actual->anterior->siguiente=nuevo_elemento;
                    nuevo_elemento->anterior=actual->anterior;
                    actual->anterior=nuevo_elemento;
                }
                break;

            }else
            {   if(actual->siguiente!=NULL)
                {
                    actual=actual->siguiente;
                }else
                {
                    nuevo_elemento->siguiente=NULL
                    nuevo_elemento->anterior=actual
                    actual->siguiente=nuevo_elemento;
                    break;

                }
            }
        }

    }


}

void ordenar(lista *tas)
{
    nodo    *actual;

    actual=tas->inicio;



}

void devuelveelemento (lista *tas,n)
{
    int i;
    i=0;
    nodo *actual;
    actual=tas->inicio;
    while(i<n)
    {

        actual=actual->siguiente;
        if(actual->siguiente==NULL && i != n)
        {
            return -1;
        }
        i++;
    }
    return actual->dato;
}

void invertir (lista *tas)
{
    nodo *actual;
    nodo *actual2;
    int copia;
    actual=tas->inicio;
    actual2=tas->inicio;
    int i,cont;
    cont=0;
    i=0;


    while(1)
    {
        if(actual2->siguiente==NULL)
        {
            break;
        }
        actual2=actual2->siguiente;
        i++;

    }

    while(cont<i/2)
    {
        copia=actual->dato;
        actual->dato=actual2->dato;
        actual2->dato=copia;

        actual2=actual2->anterior;
        actual=actual->siguiente;
        cont++;
    }


}

void menoralprincipio(lista* tas)
{
    nodo *actual;
    nodo*copia;
    int menor;

    menor=actual->dato;
    actual=actual->siguiente;
    while(actual->siguiente!=NULL)
    {
        if(actual->dato<menor)
        {
            menor=actual->dato;
            copia=actual;

        }
            actual=actual->siguiente;

    }

    while(1)
    {
        if(copia->anterior==NULL)
        {
            break;
        }else if(copia->siguiente==NULL)
        {
            copia->anterior->siguiente=NULL;
            copia->siguiente=tas->inicio;
            tas->inicio->anterior=copia;
            copia->anterior=NULL;
        }else{
            nodo *hola;
            nodo *chau;
            hola=copia->anterior;
            chau=copia->siguiente;
            copia->siguiente=tas->inicio;
            copia->anterior=NULL;
            tas->inicio->anterior=copia;
            hola->siguiente=chau;
            chau->anterior=hola;

        }

    }





}

void mayoralfinal(lista*tas)
{
    nodo *actual;
    nodo*copia;
    int mayor;

    mayor=actual->dato;
    actual=actual->siguiente;
    while(actual->siguiente!=NULL)
    {
        if(actual->dato>mayor)
        {
            mmayor=actual->dato;
            copia=actual;

        }
            actual=actual->siguiente;

    }

    while(1)
    {
        if(copia->siguiente=NULL)
        {
            break;
        }else if(copia->anterior=NULL)
        {
            tas->inicio=copia->siguiente;
            copia->siguiente->anterior=NULL;
            copia->anterior=actual;
            actual->siguiente=copia;
            copia->siguiente=NULL;
        }else
        {
            nodo *hola;
            nodo *chau;
            hola=copia->anterior;
            chau=copia->siguiente;

            copia->anterior=actual;
            copia->siguiente=NULL;
            actual->siguiente=copia;

            hola->siguiente=chau;
            chau->anterior=hola;
        }

    }
}


